<?php

namespace Yousheng\Ku;

use Illuminate\Support\Str;
use Stringable;

/**
 * 01 普通索引 INDEX idx_name (name)
 *   "type" => "btree","unique" => false,"primary" => false
 * 02 唯一索引 UNIQUE INDEX idx_email (email)
 *   "type" => "btree","unique" => true,"primary" => false
 * 03 主键索引 id INT PRIMARY KEY,
 *  "type" => "btree","unique" => true,"primary" => true
 * 04 全文索引 FULLTEXT INDEX idx_content (content)
 *  "type" => "fulltext","unique" => false,"primary" => false
 * 05 复合索引 INDEX idx_customer_date (customer_id, order_date)
 *  "type" => "btree","unique" => false,"primary" => false ，普通复合索引与普通索引差别就是多多
 * 06 空间索引 SPATIAL INDEX idx_location (location)
 *  "type" => "spatial","unique" => false,"primary" => false
 */

/* 
Laravel中相应的命令有
$table->primary('id');	添加一个主键。
$table->primary(['id', 'parent_id']);	添加复合主键。
$table->unique('email');	添加一个唯一索引。
$table->index('state');	添加一个基础索引。
$table->fullText('body');	添加一个全文索引（MySQL / PostgreSQL）。
$table->fullText('body')->language('english');	添加一个指定语言的全文索引（PostgreSQL）。
$table->spatialIndex('location');	添加一个空间索引（SQLite 除外）。 
*/


final class Index implements Stringable
{
    /**
     * ForeignKey constructor.
     *
     * @param  string  $name  索引名字，如 optionbuilder__settings_section_key_unique 表名_字段1_字段2_unique|primary
     * @param  string  $table  表名
     * @param  array<string>  $columns 列/组合例|复合索引
     * @param  bool  $unique  唯一索引
     * @param  bool  $primary  主键索引
     */
    public function __construct(
        public string $name,
        public string $type,
        public string $table,
        public array $columns,
        public bool $unique,
        public bool $primary,
    ) {}

    /**
     * Get column information array.
     *
     * @return array 当前表所索引信息
     */
    public function toArray(): array
    {
        return [
            'name' => $this->name,
            'type' => $this->type,
            'table' => $this->table,
            'columns' => $this->columns,
            'unique' => $this->unique,
            'primary' => $this->primary
        ];
    }

    /**
     * Create a instance.
     *
     * @param  string  $name  索引名字
     * @param  string  $table  Table name
     * @param  array  $columns  Column name
     * @param  string  $unique  唯一索引
     * @param  string  $primary  主键索引
     */
    public static function make(
        string $name,
        string $type,
        string $table,
        array $columns,
        string $unique,
        string $primary,
    ): static {
        return new self(
            $name,
            $type,
            $table,
            $columns,
            $unique,
            $primary,
        );
    }

    /**
     * Get the belongsTo relation from this model to another.
     *
     * @return string The method returns a relation function string
     */
    public function belongsTo(): string
    {
        return '';
    }

    /**
     * Get the hasMany relation from another model to this.
     *
     * @return string The method returns a relation function string
     */
    public function hasMany(): string
    {
        return '';
    }

    /**
     * Class magic method to get the instance information for a Exception
     *
     * @return string The method returns the instance information for a Exception
     */
    public function __toString(): string
    {
        return '索引名字为 ' . $this->name . ' ，表名是 ' . $this->table . '.';
    }

    public function migration(): string
    {
        $str = '';
        $columns = $this->indexArrayToString(array_values($this->columns));
        // 主键
        if ($this->primary === true && $this->unique === true && $this->type === 'btree') {
            $str = "\$table->primary($columns);";
        }
        // 唯一键
        if ($this->primary === false && $this->unique === true && $this->type === 'btree') {
            $str = "\$table->unique($columns);";
        }
        // 普通索引
        if ($this->primary === false && $this->unique === false && $this->type === 'btree') {
            $str = "\$table->index($columns);";
        }
        // 全文索引
        if ($this->primary === false && $this->unique === false && $this->type === 'fulltext') {
            $str = "\$table->fullText($columns);";
        }
        if ($this->primary === false && $this->unique === false && $this->type === 'spatial') {
            $language = app()->getLocale();
            $str = "\$table->spatialIndex('{$columns}')->language('{$language}');";
        }
        // 可以考虑将上面的方法改为变量
        return $str;
    }

    /* array:6 [
        "articles" => array:2 [
          0 => array:5 [
            "name" => "idx_content"
            "columns" => array:1 [
              0 => "content"
            ]
            "type" => "fulltext"
            "unique" => false
            "primary" => false
          ]
          1 => array:5 [
            "name" => "primary"
            "columns" => array:1 [
              0 => "id"
            ]
            "type" => "btree"
            "unique" => true
            "primary" => true
          ]
        ]
        "blog" => array:1 [
          0 => array:5 [
            "name" => "primary"
            "columns" => array:1 [
              0 => "id"
            ]
            "type" => "btree"
            "unique" => true
            "primary" => true
          ]
        ]
        "customer" => array:2 [
          0 => array:5 [
            "name" => "idx_email"
            "columns" => array:1 [
              0 => "email"
            ]
            "type" => "btree"
            "unique" => true
            "primary" => false
          ]
          1 => array:5 [
            "name" => "primary"
            "columns" => array:1 [
              0 => "id"
            ]
            "type" => "btree"
            "unique" => true
            "primary" => true
          ]
        ]
        "orders" => array:2 [
          0 => array:5 [
            "name" => "idx_customer_date"
            "columns" => array:2 [
              0 => "customer_id"
              1 => "order_date"
            ]
            "type" => "btree"
            "unique" => false
            "primary" => false
          ]
          1 => array:5 [
            "name" => "primary"
            "columns" => array:1 [
              0 => "id"
            ]
            "type" => "btree"
            "unique" => true
            "primary" => true
          ]
        ]
        "places" => array:2 [
          0 => array:5 [
            "name" => "idx_location"
            "columns" => array:1 [
              0 => "location"
            ]
            "type" => "spatial"
            "unique" => false
            "primary" => false
          ]
          1 => array:5 [
            "name" => "primary"
            "columns" => array:1 [
              0 => "id"
            ]
            "type" => "btree"
            "unique" => true
            "primary" => true
          ]
        ]
        "users" => array:2 [
          0 => array:5 [
            "name" => "idx_name"
            "columns" => array:1 [
              0 => "name"
            ]
            "type" => "btree"
            "unique" => false
            "primary" => false
          ]
          1 => array:5 [
            "name" => "primary"
            "columns" => array:1 [
              0 => "id"
            ]
            "type" => "btree"
            "unique" => true
            "primary" => true
          ]
        ]
      ]  */

    public function indexArrayToString($array): ?string
    {
        if(empty($array)){
            return null;
        }
        if(count($array)===1){
            return "'{$array[0]}'";
        }
        $pairs = [];
        foreach ($array as $key => $value) {
            $pairs[] = "'$value'";
        }
        return "[" . implode(",", $pairs) . "]";
    }
}
